package com.bsbm.webservice.consumers.impl;

import com.bsbm.webservice.consumers.GeoIpServiceClient;
import com.bsbm.webservice.request.GeoIPRequest;
import com.bsbm.webservice.response.GeoIPResponse;

import javax.xml.soap.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
/**
 * Created with IntelliJ IDEA.
 * User: SABIR IQBAL
 * Date: 1/7/14
 * Time: 11:15 PM
 * To change this template use File | Settings | File Templates.
 * Ref : http://stackoverflow.com/questions/15940234/how-to-do-a-soap-web-service-call-from-java-class
 * Ref : http://www.mkyong.com/java/jaxb-hello-world-example/
 */
public class GeoIpServiceClientImpl implements GeoIpServiceClient {
    @Override
    public GeoIPResponse getGeoForIP(GeoIPRequest request) {
        invoke(request.getIpAddress());
        return null;
    }

    public void invoke(String ipAddress) {
        try {
            // Create SOAP Connection
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConnection = soapConnectionFactory.createConnection();

            // Send SOAP Message to SOAP Server
            String url = "http://www.webservicex.net/geoipservice.asmx";
            SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(ipAddress), url);

            // Process the SOAP Response
            printSOAPResponse(soapResponse);

            soapConnection.close();
        } catch (Exception e) {
            System.err.println("Error occurred while sending SOAP Request to Server");
            e.printStackTrace();
        }
    }

    private SOAPMessage createSOAPRequest(String ipAddress) throws Exception {
        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage soapMessage = messageFactory.createMessage();
        SOAPPart soapPart = soapMessage.getSOAPPart();

        String serverURI = "http://www.webservicex.net/";

        // SOAP Envelope
        SOAPEnvelope envelope = soapPart.getEnvelope();
        envelope.addNamespaceDeclaration("example", serverURI);

        /*
        Constructed SOAP Request Message:
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:example="http://www.webservicex.net/">
           <soapenv:Header/>
           <soapenv:Body>
              <example:GetGeoIP>
                 <example:IPAddress>173.194.126.178</example:IPAddress>
              </example:GetGeoIP>
           </soapenv:Body>
        </soapenv:Envelope>
         */

        // SOAP Body
        SOAPBody soapBody = envelope.getBody();
        SOAPElement soapBodyElem = soapBody.addChildElement("GetGeoIP", "example");
        SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("IPAddress", "example");
        soapBodyElem1.addTextNode(ipAddress);

        MimeHeaders headers = soapMessage.getMimeHeaders();
        headers.addHeader("SOAPAction", serverURI  + "GetGeoIP");

        soapMessage.saveChanges();

        /* Print the request message */
        System.out.print("Request SOAP Message = ");
        soapMessage.writeTo(System.out);
        System.out.println();

        return soapMessage;
    }

    /**
     * Method used to print the SOAP Response
     */
    private void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        Source sourceContent = soapResponse.getSOAPPart().getContent();
        System.out.print("\nResponse SOAP Message = ");
        StreamResult result = new StreamResult(System.out);
        transformer.transform(sourceContent, result);
    }
}
